package ua.kiev.tosik.price.modules.search.gui;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.HighlighterFactory;
import org.jdesktop.swingx.table.TableColumnExt;
import org.pushingpixels.substance.api.renderers.SubstanceDefaultTableCellRenderer;
import ua.kiev.tosik.price.models.Prices;
import ua.kiev.tosik.price.modules.search.gui.models.PricesTableModel;
import ua.kiev.tosik.price.modules.search.gui.models.PricesTransferHandler;

import javax.swing.*;
import javax.swing.event.RowSorterEvent;
import javax.swing.event.RowSorterListener;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

public class PricesTable {

	private static Logger logger = Logger.getLogger("ua.kiev.tosik.price.modules.search.gui");
	private MainPanel mainPanel;
	private JXTable table;
	private PricesTableModel model;
	private DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
	private DecimalFormat df = new DecimalFormat("##,###.##");

	private int currentSortColumn = -1;
	private String currentSortType = null;

	// private int[] selectedRows = new int[0];

	public PricesTable(MainPanel mainPanel) {
		this.mainPanel = mainPanel;
		model = new PricesTableModel(new Vector<Prices>());
		table = new JXTable(model);
		table.setFillsViewportHeight(true);
		// ListSelectionModel listMod = table.getSelectionModel();
		// listMod.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		table.setRowSelectionAllowed(true);
		table.setColumnSelectionAllowed(true);
		table.setCellSelectionEnabled(true);

		table.addHighlighter(HighlighterFactory.createSimpleStriping());
		table.setColumnControlVisible(true);
		table.packAll();
		
		TableColumn tableColumn = table.getColumnModel().getColumn(0);
		tableColumn.setMinWidth(16);
		tableColumn.setMaxWidth(50);
		tableColumn.setPreferredWidth(45);

		table.setDragEnabled(true);
		table.setTransferHandler(new PricesTransferHandler(this));

		table.getRowSorter().addRowSorterListener( new RowSorterListener() {
			@Override
			public void sorterChanged(RowSorterEvent e) {
				if ( "SORTED".equals(e.getType().toString()) ) {
					if ( e.getSource().getSortKeys().size() > 0 ) {
						int sortCol = ((RowSorter.SortKey)e.getSource().getSortKeys().get(0)).getColumn();
						String sortType = ((RowSorter.SortKey)e.getSource().getSortKeys().get(0)).getSortOrder().name();
						if ( sortCol != currentSortColumn || !currentSortType.equals(sortType) ) {
							currentSortColumn = sortCol;
							currentSortType = sortType;
							// reloadData();
						}
					}
				}
			}
		});

		// table.setDefaultRenderer(Object.class, new MultiLineCellRenderer());

		TableColumnExt firstColumn = table.getColumnExt(0);
		firstColumn.setSortable(false);

		TableColumn nameColumn = table.getColumnModel().getColumn(4);
		nameColumn.setCellRenderer(new SubstanceDefaultTableCellRenderer() {
			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
				JLabel component = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				// setHorizontalAlignment(SwingConstants.CENTER);
				component.setText((value == null) ? "" : "<html>" + value.toString() + "</html>");
				// component.setToolTipText(getText());
				return component;
			}
		});
		// nameColumn.setCellRenderer(new MultiLineCellRenderer());

		TableColumn priceColumn = table.getColumnModel().getColumn(5);
		priceColumn.setCellRenderer(new SubstanceDefaultTableCellRenderer() {
			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
				Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				setHorizontalAlignment(SwingConstants.RIGHT);
				setForeground(Color.BLUE);
				return this;
			}

			@Override
			protected void setValue(Object value) {
				// super.setValue(value);
				super.setValue(df.format(value));
			}
		});

		TableColumn pricePercentColumn = table.getColumnModel().getColumn(6);
		pricePercentColumn.setCellRenderer(new SubstanceDefaultTableCellRenderer() {
			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
				Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				setHorizontalAlignment(SwingConstants.RIGHT);
				// setForeground(new Color(0, 66, 0));
				return this;
			}

			@Override
			protected void setValue(Object value) {
				// super.setValue(value);
				super.setValue(df.format(value));
			}
		});

		TableColumn dateColumn = table.getColumnModel().getColumn(7);
		dateColumn.setCellRenderer(new SubstanceDefaultTableCellRenderer() {
			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
				Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				setHorizontalAlignment(SwingConstants.CENTER);
				return this;
			}

			@Override
			protected void setValue(Object value) {
				super.setValue(dateFormat.format(value));
			}
		});

		table.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
					int row = table.convertRowIndexToModel(table.getSelectedRow());
					if ( row >= 0 ) {
						// getModel().getRow(row).setSelected(!getModel().getRow(row).isSelected());
						// getModel().fireTableRowsUpdated(row, row);
						viewPrice(row);
					}
				}
			}

			public void mouseReleased(MouseEvent e) {
				if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3) {
					table.setEditingRow(table.rowAtPoint(e.getPoint()));
					// final int row = table.getSelectedRow();
					// table.setEditingRow( table.rowAtPoint(e.getPoint()) ); // For JTable
					// contextMenu.show(e.getComponent(), e.getX(), e.getY());
				}
			}
		});

		table.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				int c = e.getKeyCode();
				if (c == KeyEvent.VK_ENTER) {
					e.consume();
					int row = table.convertRowIndexToModel(table.getSelectedRow());
					if (row >= 0) {
						// editRecord(table.getSelectedRow());
					}
				}
				if (c == KeyEvent.VK_SPACE) {
					e.consume();
					int[] rows = table.getSelectedRows();
					if (rows.length > 0) {
						for (int row : rows) {
							int r = table.convertRowIndexToModel(row);
							getModel().getRow(r).setSelected(!getModel().getRow(r).isSelected());
							getModel().fireTableRowsUpdated(r, r);
						}
						// getModel().fireTableRowsUpdated(table.convertRowIndexToModel(rows[0]), table.convertRowIndexToModel(rows[rows.length - 1]));
					}
				}
				if (c == KeyEvent.VK_C) {
					e.consume();
					int rows[] = table.getSelectedRows();
					int cells[] = table.getSelectedColumns();
					copyDataToClipboard(rows, cells);
				}
			}
		});
	}

	public int getCurrentSortColumn() {
		return currentSortColumn;
	}

	public String getCurrentSortType() {
		return currentSortType;
	}

	public void viewPrice(int rowIndex) {
		mainPanel.viewPrices(rowIndex);
	}

	private void reloadData() {
		if ( mainPanel.getResPerPage() >= mainPanel.getPricesDao().getRecordCount() ) {
			return;
		}
		try {
			mainPanel.loadData();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	public void copyDataToClipboard(int[] rows, int[] cells) {
		// ClipboardTools tableTextContent = new ClipboardTools();
		StringBuilder sb = new StringBuilder();
		String delim = "\t";
		for (int row : rows) {
			int convertedRow = table.convertRowIndexToModel(row);
			Prices prices = getModel().getRow(convertedRow);
			List<String> fieldsList = new ArrayList<String>();
			for (int p : cells) {
				int convertedCell = table.convertColumnIndexToModel(p);
				switch (convertedCell) {
					case 0:
						fieldsList.add(String.valueOf(prices.getId()));
						break;
					case 1:
						fieldsList.add(prices.getClientsName());
						break;
					case 2:
						fieldsList.add(prices.getArticleInternal());
						break;
					case 3:
						fieldsList.add(prices.getArticle());
						break;
					case 4:
						fieldsList.add(prices.getName());
						break;
					case 5:
						fieldsList.add(String.valueOf(prices.getPrice()).replaceAll("\\.", ","));
						break;
					case 6:
						fieldsList.add(String.valueOf(prices.getPricePercent()).replaceAll("\\.", ","));
						break;
					case 7:
						fieldsList.add(prices.getPricesDate().toString());
						break;
					case 8:
						fieldsList.add(prices.getExistence());
						break;
				}
			}
			if (fieldsList.size() > 0) {
				sb.append(StringUtils.join(fieldsList, delim)).append("\n");
			}
		}
		if (sb.length() >= 0) {
			// DataFlavor csv = new DataFlavor("text/csv", "Comma-Separated Values (CSV)");
			Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
			Transferable transferableText = new StringSelection(sb.toString());
			systemClipboard.setContents(transferableText, null);
		}
	}

	public JXTable getTable() {
		return table;
	}

	public PricesTableModel getModel() {
		return model;
	}
	
//	private class MultiLineCellRenderer extends JTextArea implements TableCellRenderer {
//
//		public MultiLineCellRenderer() {
//			setLineWrap(true);
//			setWrapStyleWord(true);
//			setOpaque(true);
//		}
//
//		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
//			if (isSelected) {
//				setForeground(table.getSelectionForeground());
//				setBackground(table.getSelectionBackground());
//			} else {
//				setForeground(table.getForeground());
//				setBackground(table.getBackground());
//			}
//			setFont(table.getFont());
//			if (hasFocus) {
//				setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
//				if (table.isCellEditable(row, column)) {
//					setForeground(UIManager.getColor("Table.focusCellForeground"));
//					setBackground(UIManager.getColor("Table.focusCellBackground"));
//				}
//			} else {
//				setBorder(new EmptyBorder(1, 2, 1, 2));
//			}
//			setText((value == null) ? "" : value.toString());
//			/*
//			int rowHeight = getPreferredSize().height;
//			if (table.getRowHeight(row) != rowHeight) table.setRowHeight(row, rowHeight); */
//			/*
//			int rowHeight = (int)getPreferredSize().getHeight();
//			if (table.getRowHeight(row) != rowHeight) table.setRowHeight(row, rowHeight);
//			*/
//			return this;
//		}
//	}

}
